(function(window) {
    // 把三个状态设为常量
    const PENDING = 'pending'
    const FULFILLED = 'fulfilled'
    const REJECTED = "rejected"
    function Promise(excutor) {
        // 设置构造函数的属性
        this.state = PENDING; //默认值
        this.data = undefined; //默认值
        // 保存待处理回调的数组: [{resolved () {}, rejected () {}}, {resolved () {}, rejected () {}}] => callbacks
        this.callbacks = []
        let self = this;
        function resolve (value) {
            // 原因：只有当前状态为pending， 才会去改变状态，继续向下处理 （只改变一次，处理 resolve(11),后面紧跟reject() 的状态，只执行第一个，后面的不执行）
            if (self.state !== PENDING) return ;
            self.state = FULFILLED;
            self.data = value;
            setTimeout(() => {
                console.log('执行了由pending状态改为resolve的待处理回调函数，value值为', value);
                self.callbacks.forEach(callbackObj => callbackObj.resolved(value))
            } , 0)
        }
        function reject(reason) {
            if (self.state !== PENDING) return ;
            self.state = REJECTED;
            self.data = reason;
            setTimeout(() => {
                self.callbacks.forEach(callbackObj => callbackObj.rejected(reason))
            } , 0)
        }
        // 当函数中，抛出一个错误时
        try {
            excutor(resolve, reject);//执行器函数是回调函数，
        } catch (error) {
            reject(error)
        }
        
    }
    Promise.prototype.then = function(Onresolved, Onrejected) { // Onresolved, Onrejected 函数的形参，在then方法的实参
        console.log('then()');
        const self = this;
        // 如果onResolved不是函数, 指定一个默认函数, 向下传递value
        Onresolved = typeof Onresolved === 'function' ? Onresolved : value => value;
        // 如果onRejected不是函数, 指定一个默认函数, 向下传递reason
        Onrejected = typeof Onrejected === 'function' ? Onrejected : reason => {throw reason};
        
        //resolve直接执行的时候，then中的Onresolved，开始异步读取resolve的结果，即 成功状态的promise，异步执行成功的回调
        return new Promise((resolve, reject) => {
            function handle(callback) {
                try {
                    let result = callback(self.data);
                    if (result instanceof Promise) {
                        //1.回调函数的结果为promise，则此时then返回的promise状态和结果，就为 此时promise的成功或失败状态的值
                        result.then(value => {
                            resolve(value);
                        }, reason => {
                            reject(reason);
                        })
                    } else {
                        //2.非promis的值,返回成功的状态
                        resolve(result)
                    }   
                } catch (error) {
                    // 3.结果中抛出错误
                    reject(error);
                }
            }
            if(self.state === FULFILLED) {
                setTimeout(() => {
                    // console.log('resolve直接执行的时候,执行回调');
                    handle(Onresolved)
                }, 0);
            } else if (self.state === REJECTED) {
                setTimeout(() => {
                    handle(Onrejected);
                }, 0);
            }else {
                // 待处理的回调
                this.callbacks.push({
                    resolved: () => {
                        // console.log('resolve待处理执行的时候,执行回调');
                        handle(Onresolved)
                    },
                    rejected: () => {
                        console.log('reject待处理执行的时候,执行回调');
                        handle(Onrejected);
                    }
                })
            }
        }) 

    }
    Promise.prototype.catch = function(Onresolved, Onrejected) {
       return this.then(Onrejected);
    }
    // 
    Promise.prototype.finally = function(Onfinal) {
        const self = this;
        return new Promise((resolve, reject) => {
            self.then(value => {
                Onfinal();
                resolve(value);
            }, reason => {
                Onfinal();
                reject(reason);
            })
            Onfinal();
        })
    }

    Promise.resolve = function (value) {

    }
    Promise.reject = function (reason) {
        
    }
    Promise.all = function (promises) {

    }
    Promise.race = function (promises) {
        
    }
    Promise.allSettled = function (promises) {

    }
    
    window.Promise = Promise;
})(window)